#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QTcpSocket>
#include <QUdpSocket>
#include <QNetworkDatagram>
#include <QFile>
#include <QDataStream>
#include <QByteArray>
#include <QMessageBox>
#include <QElapsedTimer>
#include <QTimer>

#define TCP_SERVER_PORT 44444
#define UDP_SERVER_PORT 12345
#define UDP_CLIENT_PORT 54321
#define READ_BUFFER 50//2*1024   // 系统buffer默认最大容量为64*1024字节,超过无效
#define PAYLOADSIZE 64*1024 // 服务器每次发送块的大小n*1024B=nKB

const qint64 cmd_sendIpAndHostName = 111;
const qint64 cmd_dataCollectionStart = 222;
const qint64 cmd_dataCollectionStop = 333;
const qint64 cmd_faultDiagnosis = 444;
const qint64 cmd_stopTransmition = 555;

extern QList<QList<QString>>IpAndHostName;
extern QMap<QString,QString>Map_AvoidReopenWidgets;

enum _DataType
{
    TYPE_CMD=1, TYPE_DATA=2, TYPE_FILE=3, TYPE_INFO=4
};

class TcpClient: public QTcpSocket
{
    Q_OBJECT
public:
    TcpClient(const QString &addr, const quint16 &port = TCP_SERVER_PORT, QObject *parent = nullptr);
    ~TcpClient();
    bool processDataPacket(qint8 type);

public slots:
    void dataCollection(const qint64 cmd, QString path = "");//通过信号把路径信息传过来，在新线程内直接存文件
    void createConnection();
    void closeConnection();
    void readyReceive();
    void sendCommand(qint64 cmd);
    void readySend();
    void tcpStateChange();

signals:
    void tcpStateChanged(QAbstractSocket::SocketState state);
    void dataCollectionProgress(float speed, float receiveSize,float totalSize);
    void faultDiagnosisResults(QString result);
    void serverInformation(QString result);
    void textLabel(QString text);

private:
    QFile var_newFiles;
    QString var_filePath;
    QString var_fileName;
    QString var_ip;
    quint16 var_port;
    // 接收
    QByteArray var_tempReceiveData;
    qint8 var_packetType;
    qint64 var_packetReceiveSize; // 已接收的大小
    qint64 var_fileBytesRecv;
    qint64 var_dataBytesRecv;
    qint64 var_fileTotalBytes;
    qint64 var_dataTotalBytes;
    qint64 var_fileNameSize;
    bool var_isCompletepacket;
    QElapsedTimer var_wasteTime;
    // 发送
    qint64 var_cmd;
};

class udpClient : public QUdpSocket
{
    Q_OBJECT
public:
    udpClient(QObject *parent = nullptr);
    virtual ~udpClient();
    bool isSuccessfullyOpen();

public slots:
    void readPendingDatagrams();
    void sendPendingDatagrams();
    void sendCommand();
    void errorOccur();

signals:
    void getIpAndName();
    void textLabel(QString text);

private:
    QString var_IpAddress;
    QString var_HostName;
    bool flag;
};

#endif // TCPCLIENT_H
